It's time to create our demo app!
We will create a Food Recipe app, we will fetch data from an API and we will use both useState and useEffect hooks.
First, create a new file under src > components and name it FoodRecipe.js.
To be able to get a response for search queries, we need an APP ID and an APP KEY.
Click on Applications > View. You should see your Application ID and Application Keys on this page.
Copy your keys and paste them inside the code.
API can give some errors, if you see any CORS errors, add a cors browser extension for the browser you are using. Firefox / Chrome
Still, there is a problem? You need to wait until your API keys are available. Also, for the free version, we can only make 5 requests per minute. You can check out the documentation.
src/components/FoodRecipe.js
importReact,{useEffect}from'react';
constFoodRecipe=()=>{
// paste your APP_ID
constAPP_ID='';
// paste your APP_KEY
constAPP_KEY='';
// url query is making a search for 'chicken' recipe
// created an async function to be able to fetch our data
constgetData=async(e)=>{
const response =awaitfetch(url);
const result =await response.json();
// console log the results we get from the api
console.log(result);
};
return(
<div>
<h1>FoodRecipeApp</h1>
<form>
<input type="text" placeholder="Search for recipes"/>
<button type="submit" className="btn">
Search
</button>
</form>
</div>
);
};
exportdefaultFoodRecipe;
Let's see what we did in our code:
Created some JSX elements(form, input, and button properties).
We are calling our function to fetch our data.
Created a fetch request to get our data, and used useEffect hook to call our function. We are using our empty dependency array because we will only make a request when our app loads.
We got our API response, and we got a lot of information. You can see from the gif. Now, we need to create a state for our recipes, and we will update the recipes with the API data. We will only extract hits and their contents from our response. Let's do it!
// set the state for our results and extract the 'hits' data from API response
setRecipes(result.hits);
};
// some ui
};
exportdefaultFoodRecipe;
Okay, here we have added our recipes state and updated with setRecipes. From our API call, we see that hits is an array, that's why for the default value we put an empty array.
We need to display our recipes, for that let's create a Recipe component.
Go to src > components, create a new component, and name it Recipe.js. Copy this code, this will allow us to display individual recipes.
Here, I have used some Semantic UI components to display our individual recipes.
src/components/Recipe.js
importReactfrom'react';
constRecipe=()=>{
return(
<div class="ui column grid">
<div className="column recipe">
<div className="content">
<h2>Label</h2>
<p>Calories:</p>
<ul>
<li>Ingredients</li>
</ul>
<a href="" target="_blank">
URL
</a>
</div>
<div className="ui fluid card">
<img />
</div>
</div>
</div>
);
};
exportdefaultRecipe;
Now, we need to map over our recipes state, and display the results.
src/components/FoodRecipe.js
// ..............
return(
<div>
<h1>FoodRecipeApp</h1>
<form>
<input type="text" placeholder="Search for recipes"/>
<button type="submit" className="btn">
Search
</button>
</form>
<div className="recipes">
{/* map over our array and pass our data from API*/}
{recipes !==[]&&
recipes.map((recipe)=>(
<Recipe
key={recipe.recipe.url}
label={recipe.recipe.label}
calories={recipe.recipe.calories}
image={recipe.recipe.image}
url={recipe.recipe.url}
ingredients={recipe.recipe.ingredients}
/>
))}
</div>
</div>
);
For now, I am getting our Recipe.js without any props, of course.
Now, we can go to our Recipe component and pass our props to it. We are getting these props from the parent FoodRecipe.js. We will use destructuring to get our props.
Now, we need to use our search bar, we will search the recipe from our input field. To get the state of our search bar, we will create a new piece of state.
Go to FoodRecipe.js and add a new search state.
src/components/FoodRecipe.js
// create a state for search query
const[search, setSearch]=useState('');
Set the value for input value search, setSearch will update our input with the onChange event handler.
The input is keeping track of its state with the search state. We can get input's value from event.target.value.
Then we can change our state with setSearch function.
src/components/FoodRecipe.js
<input
type="text"
value={search}
onChange={(event)=>setSearch(event.target.value)}
/>
We need to update our state after we click on Search Button. That's why we need another state. And we can update our url from chicken query to any query. Make a new state, name it query.
src/components/FoodRecipe.js
const[query, setQuery]=useState('');
// when you send the form, we call onSubmit handler to query the results
constonSubmit=(e)=>{
// prevent browser refresh
e.preventDefault();
// setQuery for the finished search recipe
setQuery(search);
};
Now, we need to pass our query state to our onEffect dependency array. Whenever we click on the Search button, we will call our API and change our state to a new query state.
The query will only run after the form submit. Use it as a dependency inside the array. Our final code now looks like this: